home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / utildsk / memry374.lha / memory-device / source / device.c < prev    next >
C/C++ Source or Header  |  1996-05-08  |  7KB  |  293 lines

  1. /*
  2. ** $VER: device.c 1.3 (07 May 1996)
  3. **
  4. ** memory.device - direct memory access
  5. **
  6. ** (C) Copyright 1996 Marius Gröger
  7. **     All Rights Reserved
  8. **
  9. ** Inspired by z2ram device in Linux/68k/Amiga
  10. **
  11. ** $HISTORY:
  12. **
  13. ** 07 May 1996 : 001.003 :  trackdisk emulation improved
  14. ** 29 Mar 1996 : 001.002 :  minor changes
  15. ** 10 Mar 1996 : 001.001 :  + CMD_UPDATE does CacheClearU()
  16. **                          + using CopyMemWarp()
  17. ** 20 Dec 1995 : 001.000 :  created
  18. */
  19.  
  20. #define DEBUG 0
  21.  
  22. /*F*/ /* includes */
  23. #ifndef CLIB_ALIB_PROTOS_H
  24. #include <clib/alib_protos.h>
  25. #endif
  26. #ifndef CLIB_EXEC_PROTOS_H
  27. #include <clib/exec_protos.h>
  28. #include <pragmas/exec_sysbase_pragmas.h>
  29. #endif
  30.  
  31. #ifndef EXEC_MEMORY_H
  32. #include <exec/memory.h>
  33. #endif
  34. #ifndef EXEC_IO_H
  35. #include <exec/io.h>
  36. #endif
  37. #ifndef EXEC_ERRORS_H
  38. #include <exec/errors.h>
  39. #endif
  40. #ifndef DEVICES_TRACKDISK_H
  41. #include <devices/trackdisk.h>
  42. #endif
  43.  
  44. #ifndef _STRING_H
  45. #include <string.h>
  46. #endif
  47.  
  48. #ifndef __MEMORY_H
  49. #include "memory.h"
  50. #endif
  51. #ifndef __DEBUG_H
  52. #include "debug.h"
  53. #endif
  54. #ifndef __COMPILER_H
  55. #include "compiler.h"
  56. #endif
  57. /*E*/
  58.  
  59. /*F*/ /* imports */
  60. PUBLIC ASM VOID CopyMemWarp(REG(a0) VOID *src, REG(a1) VOID *dst, REG(d0) ULONG len);
  61. /*E*/
  62. /*F*/ /* exports */
  63. PUBLIC ASM SAVEDS struct Device *DevInit(REG(d0) BASEPTR, REG(a0) ULONG seglist, REG(a6) struct Library *_SysBase);
  64. PUBLIC ASM SAVEDS LONG DevOpen(REG(a1) struct IOExtTD *iotd, REG(d0) ULONG unit, REG(d1) ULONG flags, REG(a6) BASEPTR);
  65. PUBLIC ASM SAVEDS BPTR DevExpunge(REG(a6) BASEPTR);
  66. PUBLIC ASM SAVEDS BPTR DevClose( REG(a1) struct IOExtTD *ior, REG(a6) BASEPTR);
  67. PUBLIC VOID DevTermIO(BASEPTR, struct IOExtTD *iotd);
  68. PUBLIC ASM SAVEDS VOID DevBeginIO(REG(a1) struct IOExtTD *iotd, REG(a6) BASEPTR);
  69. PUBLIC ASM SAVEDS LONG DevAbortIO(REG(a1) struct IOExtTD *ior, REG(a6) BASEPTR);
  70. /*E*/
  71. /*F*/ /* private */
  72. /*E*/
  73.  
  74.  
  75.    /*
  76.    ** initialise device
  77.    */
  78. /*F*/ PUBLIC ASM SAVEDS struct Device *DevInit(REG(d0) BASEPTR, REG(a0) ULONG seglist, REG(a6) struct Library *_SysBase)
  79. {
  80.    BOOL ok;
  81.    UBYTE *p;
  82.    UWORD i;
  83.  
  84.    d(("entered device, initialising device base...\n"));
  85.  
  86.       /* clear data base */
  87.    for(p = ((UBYTE*)mb) + sizeof(struct Library), i = sizeof(struct MemoryBase)-sizeof(struct Library); i; i--)
  88.       *p++ = 0;
  89.  
  90.    SysBase = _SysBase;
  91.  
  92.    mb->mb_SegList = seglist;           /* store DOS segment list */
  93.  
  94.    InitSemaphore(&mb->mb_Lock);
  95.  
  96.    ok = TRUE;
  97.  
  98.    d(("left %ld\n",ok));
  99.  
  100.    return (struct Device *)(ok ? mb : NULL);
  101. }
  102. /*E*/
  103.  
  104.    /*
  105.    ** open device
  106.    */
  107. /*F*/ PUBLIC ASM SAVEDS LONG DevOpen(REG(a1) struct IOExtTD *iotd, REG(d0) ULONG unit, REG(d1) ULONG flags, REG(a6) BASEPTR)
  108. {
  109.    LONG rv = 0;
  110.  
  111.    d(("entered\n"));
  112.  
  113.    /* Make sure our open remains single-threaded. */
  114.    ObtainSemaphore(&mb->mb_Lock);
  115.    mb->mb_DevNode.lib_OpenCnt++;
  116.    mb->mb_DevNode.lib_Flags &= ~LIBF_DELEXP;
  117.    ReleaseSemaphore(&mb->mb_Lock);
  118.  
  119.    iotd->iotd_Req.io_Error = 0;
  120.    iotd->iotd_Req.io_Unit = NULL;
  121.    iotd->iotd_Req.io_Device = (struct Device *)mb;
  122.    iotd->iotd_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
  123.  
  124.    return rv;
  125. }
  126. /*E*/
  127.  
  128.    /*
  129.    ** close device
  130.    */
  131. /*F*/ PUBLIC ASM SAVEDS BPTR DevClose(REG(a1) struct IOExtTD *ior, REG(a6) BASEPTR)
  132. {
  133.    BPTR seglist;
  134.  
  135.    d2(("entered\n"));
  136.  
  137.       /* invalidate IO request block */
  138.    ior->iotd_Req.io_Device = (struct Device *)-1;
  139.    ior->iotd_Req.io_Unit = (struct Unit *)-1;
  140.  
  141.    ObtainSemaphore(&mb->mb_Lock);
  142.  
  143.    mb->mb_DevNode.lib_OpenCnt--;
  144.  
  145.    ReleaseSemaphore(&mb->mb_Lock);
  146.  
  147.    if (mb->mb_DevNode.lib_Flags & LIBF_DELEXP)
  148.       seglist = DevExpunge(mb);
  149.    else
  150.       seglist = 0;
  151.  
  152.    return seglist;
  153. }
  154. /*E*/
  155. /*F*/ PUBLIC ASM SAVEDS BPTR DevExpunge(REG(a6) BASEPTR)
  156. {
  157.    BPTR seglist;
  158.  
  159.    d2(("entered\n"));
  160.  
  161.    if (mb->mb_DevNode.lib_OpenCnt)
  162.    {
  163.       mb->mb_DevNode.lib_Flags |= LIBF_DELEXP;
  164.       seglist = 0;
  165.    }
  166.    else
  167.    {
  168.          /* detach device from system list */
  169.       Remove((struct Node*)mb);
  170.  
  171.          /* save seglist for return value */
  172.       seglist = (long)mb->mb_SegList;
  173.  
  174.          /* return memory
  175.          **
  176.          ** NO FURTHER ACCESS TO DEVICE BASE ALLOWED!
  177.          */
  178.       FreeMem(((char *)mb) - mb->mb_DevNode.lib_NegSize,
  179.          (ULONG)(mb->mb_DevNode.lib_PosSize + mb->mb_DevNode.lib_NegSize));
  180.    }
  181.  
  182.    return seglist;
  183. }
  184. /*E*/
  185.  
  186.    /*
  187.    ** initiate io command (1st level dispatcher)
  188.    */
  189. #if 0
  190. /*F*/ static INLINE VOID DevForwardIO(BASEPTR, struct IOExtTD *iotd)
  191. {
  192.    d(("forwarding request %ld\n", iotd->iotd_Req.io_Command));
  193.  
  194.    /* request is no longer of type "quick i/o" */
  195.    iotd->iotd_Req.io_Flags &= ~IOF_QUICK;
  196.    PutMsg(mb->mb_ServerPort, (struct Message*)iotd);
  197. }
  198. /*E*/
  199. #endif
  200. /*F*/ PUBLIC INLINE VOID DevTermIO(BASEPTR, struct IOExtTD *iotd)
  201. {
  202.    d(("cmd = %ld, error = %ld\n", iotd->iotd_Req.io_Command, iotd->iotd_Req.io_Error));
  203.  
  204.                   /* if this command was done asynchonously, we must
  205.                   ** reply the request
  206.                   */
  207.    if(!(iotd->iotd_Req.io_Flags & IOF_QUICK))
  208.       ReplyMsg((struct Message *)iotd);
  209.    else           /* otherwise just mark it as done */
  210.       iotd->iotd_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
  211. }
  212. /*E*/
  213. /*F*/ PUBLIC ASM SAVEDS VOID DevBeginIO(REG(a1) struct IOExtTD *iotd, REG(a6) BASEPTR)
  214. {
  215.       /* mark request as active */
  216.    iotd->iotd_Req.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  217.    iotd->iotd_Req.io_Error = 0;
  218.  
  219.    d(("cmd = %ld\n",iotd->iotd_Req.io_Command));
  220.  
  221.    switch(iotd->iotd_Req.io_Command)
  222.    {
  223.       case CMD_READ:
  224.          d(("CMD_READ 0x%08lx bytes from 0x%08lx to 0x%08lx\n",
  225.                      iotd->iotd_Req.io_Length,
  226.                      iotd->iotd_Req.io_Offset,
  227.                      iotd->iotd_Req.io_Data));
  228.          CopyMemWarp((UBYTE*)iotd->iotd_Req.io_Offset, (UBYTE*)iotd->iotd_Req.io_Data,
  229.                   (ULONG)iotd->iotd_Req.io_Length);
  230.          iotd->iotd_Req.io_Actual = iotd->iotd_Req.io_Length;
  231.       break;
  232.  
  233.       case CMD_WRITE:
  234.          d(("CMD_WRITE 0x%08lx bytes to 0x%08lx from 0x%08lx\n",
  235.                      iotd->iotd_Req.io_Length,
  236.                      iotd->iotd_Req.io_Offset,
  237.                      iotd->iotd_Req.io_Data));
  238.          CopyMemWarp((UBYTE*)iotd->iotd_Req.io_Data, (UBYTE*)iotd->iotd_Req.io_Offset,
  239.                   (ULONG)iotd->iotd_Req.io_Length);
  240.          iotd->iotd_Req.io_Actual = iotd->iotd_Req.io_Length;
  241.       break;
  242.  
  243.       case CMD_UPDATE:
  244.          CacheClearU();
  245.       break;
  246.  
  247.       case CMD_RESET:
  248.       case CMD_CLEAR:
  249.       case CMD_STOP:
  250.       case CMD_START:
  251.       case TD_FORMAT:
  252.       case TD_SEEK:
  253.       break;
  254.  
  255.       case TD_PROTSTATUS:
  256.          iotd->iotd_Req.io_Actual = 0; /* not protected */
  257.       break;
  258.  
  259.       case TD_MOTOR:
  260.          iotd->iotd_Req.io_Actual = 0;
  261.       break;
  262.  
  263.       case TD_CHANGENUM:
  264.          iotd->iotd_Req.io_Actual = 1;
  265.       break;
  266.  
  267.       case TD_CHANGESTATE:
  268.          iotd->iotd_Req.io_Actual = 0;
  269.       break;
  270.  
  271.       default:
  272.          iotd->iotd_Req.io_Error = IOERR_NOCMD;
  273.       break;
  274.    }
  275.  
  276.    if (iotd) DevTermIO(mb, iotd);
  277.  
  278.    return;
  279. }
  280. /*E*/
  281.  
  282.    /*
  283.    ** stop io-command
  284.    */
  285. /*F*/ PUBLIC ASM SAVEDS LONG DevAbortIO(REG(a1) struct IOExtTD *ior, REG(a6) BASEPTR)
  286. {
  287.    d(("cmd = %ld\n",ior->iotd_Req.io_Command));
  288.  
  289.    return 0;
  290. }
  291. /*E*/
  292.  
  293.